<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>放大镜</title>
</head>

<body>
    <!-- 原图片 -->
    <canvas id="canvas" style="display: block; margin: 100px auto; border: 1px solid #aaa">
        您的浏览器尚不支持canvas
    </canvas>

    <!-- 放大镜 -->
    <canvas id="offCanvas" style="display: none"></canvas>

    <script>
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");

        var offCanvas = document.getElementById("offCanvas");
        var offContext = offCanvas.getContext("2d");

        var scale = 2; /* 放大倍数 */

        canvas.width = 500;
        canvas.height = 500;

        offCanvas.width = 500 * scale;
        offCanvas.height = 500 * scale;

        var image = new Image();
        var isMouseDown = false;

        image.src = "./img/test.jpg";
        image.onload = function () {
            /* 图片加载完成-填充到画布上 */
            context.drawImage(image, 0, 0, canvas.width, canvas.height);
            offContext.drawImage(image, 0, 0, offCanvas.width, offCanvas.height);
        };

        /* 鼠标点击 */
        canvas.onmousedown = function (e) {
            e.preventDefault(); /* 阻止默认行为 */
            isMouseDown = true;
            point = {
                x: e.offsetX,
                y: e.offsetY,
            };
            console.log(point);
            drawCanvasWithMagnifier(true, point);
        };

        /* 鼠标松开 */
        canvas.onmouseup = function (e) {
            e.preventDefault();
            isMouseDown = false;
            drawCanvasWithMagnifier(false);
        };

        /* 鼠标移出 */
        canvas.onmouseout = function (e) {
            e.preventDefault();
            isMouseDown = false;
            drawCanvasWithMagnifier(false);
        };

        /* 鼠标移动 */
        canvas.onmousemove = function (e) {
            e.preventDefault();
            if (isMouseDown) {
                point = {
                    x: e.offsetX,
                    y: e.offsetY,
                };
                console.log(point);
                drawCanvasWithMagnifier(true, point);
            }
        };

        /* 绘制放大镜 */
        function drawCanvasWithMagnifier(isShowMagnifier, point) {
            context.clearRect(0, 0, canvas.width, canvas.height); //清除画布
            context.drawImage(image, 0, 0, canvas.width, canvas.height);

            if (isShowMagnifier) {
                drawMagnIfier(point);
            }
        }

        /* 放大镜坐标计算 */
        function drawMagnIfier(point) {
            // 原图片canvas 和 放大镜canvas 对应坐标计算
            var mr = 200; /* 放大镜半径 */

            /* 放大镜坐标-中心点 */
            var imageLG_cx = point.x * scale;
            var imageLG_cy = point.y * scale;

            /* 放大镜坐标-左上点 */
            var sx = imageLG_cx - mr;
            var sy = imageLG_cy - mr;

            /* 原图片坐标-左上点 */
            var dx = point.x - mr;
            var dy = point.y - mr;

            context.save();

            context.lineWidth = 10.0;
            context.strokeStyle = "#ccc";

            /* 绘制-圆形放大器 */
            context.beginPath();
            context.arc(point.x, point.y, mr, 0, Math.PI * 2, false);
            context.stroke();
            context.clip(); /* 裁剪 */

            /* 绘制-放大镜后的图形区域 */
            context.drawImage(
                offCanvas,
                sx,
                sy,
                mr * 2,
                mr * 2,
                dx,
                dy,
                mr * 2,
                mr * 2
            );
            context.restore();
        }
    </script>
</body>

</html>